import type { AxiosInstance } from "axios";
import { createFlowableClient } from "./flowableClient";

/**
 * Flowable API 服务封装
 */
export class FlowableService {
  private client: AxiosInstance;
  private formClient: AxiosInstance;

  constructor(
    private baseURL: string,
    private username: string,
    private password: string
  ) {
    this.client = createFlowableClient(baseURL, username, password);
    // 自动推导 form-api 地址（假设与 process-api 同域）
    const formBase = baseURL.replace("process-api", "form-api");
    this.formClient = createFlowableClient(formBase, username, password);
  }

  /**
   * 切换连接配置（支持 baseURL / 用户名 / 密码）
   */
  switchConnection(baseURL: string, username: string, password: string) {
    console.log(`[FlowableService] 切换连接: ${username}@${baseURL}`);
    this.baseURL = baseURL;
    this.username = username;
    this.password = password;
    this.client = createFlowableClient(baseURL, username, password);
    const formBase = baseURL.replace("process-api", "form-api");
    this.formClient = createFlowableClient(formBase, username, password);
  }

  /** 获取所有流程定义*/
  async listProcessDefinitions(): Promise<any[]> {
    const url = `/repository/process-definitions`;
    const res = await this.client.get(url);
    return res.data.data || [];
  }

  /** 获取所有流程实例*/
  async listProcessInstances(): Promise<any[]> {
    const url = `/runtime/process-instances`;
    const res = await this.client.get(url);
    return res.data.data || [];
  }

  /** 获取 BPMN XML */
  async getProcessXML(processDefinitionId: string): Promise<string> {
    const url = `/repository/process-definitions/${processDefinitionId}/resourcedata`;
    const res = await this.client.get(url, { responseType: "text" });
    return res.data;
  }

  /** 启动流程实例（通过 processDefinitionId）
   * @param options 启动参数
   * processDefinitionId 流程定义 ID
   * businessKey 业务键（可选）
   * returnVariables 是否返回变量（默认 true）
   * variables 流程变量（可选）
   * @returns 流程实例信息
   */
  async startProcessInstance(options: {
    processDefinitionId: string;
    businessKey?: string;
    returnVariables?: boolean;
    variables?: Record<string, any>[];
  }) {
    const {
      processDefinitionId,
      businessKey = "",
      returnVariables = true,
      variables = [],
    } = options;

    const payload = {
      processDefinitionId,
      businessKey,
      returnVariables,
      variables,
    };

    const url = `/runtime/process-instances`;
    const res = await this.client.post(url, payload);
    return res.data;
  }

  /** 删除（终止）流程实例
   * @param processInstanceId 流程实例 ID
   * @param deleteReason 删除原因（可选）
   * @returns 是否删除成功
   */
  async deleteProcessInstance(
    processInstanceId: string,
    deleteReason?: string
  ) {
    const url = `/runtime/process-instances/${processInstanceId}`;
    const res = await this.client.delete(url, {
      params: deleteReason ? { deleteReason } : undefined,
    });
    return res.status === 204; // Flowable 删除成功时通常返回 204 No Content
  }

  /**
   * 获取流程定义的 BPMN XML
   * @param processDefinitionId 流程定义 ID
   * @returns BPMN XML 字符串
   */
  async getProcessXml(processDefinitionId: string) {
    const url = `/repository/process-definitions/${processDefinitionId}/resourcedata`;
    const res = await this.client.get(url, {
      responseType: "text",
    });
    return res.data;
  }

  /** 获取当前活动节点 ID 列表
   * @param processInstanceId 流程实例 ID
   * @returns 活动节点 ID 列表
   */
  async getActiveActivities(processInstanceId: string): Promise<string[]> {
    const url = `/runtime/executions/${processInstanceId}/activities`;
    const res = await this.client.get(url);
    return res.data;
  }

  /** 获取任务列表
   * @param params 可选查询参数，如 assignee(领取人), candidateUser(指定用户), candidateGroup(指定组) 等
   * @returns 任务数组
   */
  async listTasks(params?: Record<string, any>): Promise<any[]> {
    const url = `/runtime/tasks`;
    const res = await this.client.get(url, { params });
    return res.data.data || [];
  }

  /** 根据任务 ID 获取任务详情 */
  async getTask(taskId: string): Promise<any> {
    const url = `/runtime/tasks/${taskId}`;
    const res = await this.client.get(url);
    return res.data;
  }

  /** 获取任务关联表单 */
  async getTaskForm(taskId: string): Promise<any> {
    try {
      // 第一步：先拿 formDefinitionId
      const formMeta = await this.client.get(`/runtime/tasks/${taskId}/form`);
      const formDefinitionId = formMeta.data?.id;

      if (!formDefinitionId) {
        console.warn(`[FlowableService] 任务 ${taskId} 未关联表单`);
        return null;
      }

      // 第二步：切换到 form-api 获取表单定义（UTF-8，无乱码）
      const formDefRes = await this.formClient.get(
        `/form-repository/form-definitions/${formDefinitionId}/model`
      );

      return formDefRes.data;
    } catch (err) {
      console.error("获取任务表单失败：", err);
      throw err;
    }
  }

  /**
   * 提交任务表单数据，完成任务
   * @param taskId 流程实例(任务)ID
   * @param properties 表单字段数组 [{ id, name, type, value }]
   */
  async submitTaskForm(options: {
    taskId: string;
    properties?: { id: string; name?: string; type?: string; value?: any }[];
  }) {
    const url = `/form/form-data`;
    const payload = {
      taskId: options.taskId,
      properties: options.properties
    };

    const res = await this.client.post(url, payload);
    return res.data;
  }

  /**
   * 认领任务（将任务分配给某个用户）
   * @param taskId 任务ID
   * @param userId 用户ID
   * @returns 
   */
  async claimTask(taskId: string, userId: string) {
    return this.client.post(`/runtime/tasks/${taskId}`, {
      action: "claim",
      assignee: userId,
    });
  }
}
